package com.lh.java.basic.date;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期常用转换
 * 
 */
public class DateUtil {

	/**
	 * 根据时间字符串返回Date对象
	 * 
	 * @param dateStr
	 *            ,可以接受3种格式分别是:yyyy-MM-dd,yyyy-MM-dd HH:mm,yyyy-MM-dd HH:mm:ss
	 * @return
	 */

	public static Date getDateByStr(String dateStr) {
		if (StringUtils.isNotBlank(dateStr)) {
			SimpleDateFormat formatter = null;
			if (dateStr.length() == 10)
				formatter = new SimpleDateFormat("yyyy-MM-dd");
			else if (dateStr.length() == 16)
				formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			else if (dateStr.length() == 19)
				formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			else {
				return null;
			}
			try {
				return formatter.parse(dateStr);
			} catch (ParseException e) {
				return null;
			}
		}
		return null;
	}

	/***
	 * 转化日期为指定格式pengsheng
	 * **/
	public static Date ConvertDatebyStr(String datestring, String formatstring) {
		Date date = null;
		if (datestring != null && !"".equals(datestring) && formatstring != null) {
			SimpleDateFormat format = new SimpleDateFormat(formatstring);
			try {
				date = format.parse(datestring);
			} catch (ParseException e) {
				System.out.println("日期格式错误");
				e.printStackTrace();
				return date;
			}
		}
		return date;
	}

	/**
	 * 获取昨日的日期，yyyy-mMM-dd HH:mm:ss
	 * 
	 * @return
	 * @Author: seara
	 */
	public static Date getYesterday() {
		return addDay(new Date(), -1);
	}

	public static Date getYesterdayOnlyYMD() {
		return convertDateOnlyHaveYMD(getYesterday());
	}

	/**
	 * 获取昨日的日期，yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date convertDateOnlyHaveYMD(Date date) {
		return getDate(date);
	}

	/**
	 * 返回日期的字符串
	 * 
	 * @param date
	 *            Date对象
	 * @param format
	 *            例如:yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getStrByDate(Date date, String format) {
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		return formatter.format(date);
	}

	/**
	 * 返回日期的字符串,年-月-日
	 * 
	 * @param date
	 * @return yyyy-MM-dd
	 */
	public static String getStrYMDByDate(Date date) {
		if (null == date) {
			return null;
		}
		return getStrByDate(date, "yyyy-MM-dd");
	}

	/**
	 * 返回日期的字符串,时:分:秒
	 * 
	 * @param date
	 * @return HH:mm:ss
	 */
	public static String getStrHMSByDate(Date date) {
		return getStrByDate(date, "HH:mm:ss");
	}

	/**
	 * 返回日期的字符串,年-月-日 时:分:秒
	 * 
	 * @param date
	 * @return yyyy-MM-dd HH:mm:ss
	 */
	public static String getStrYMDHMSByDate(Date date) {
		return getStrByDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 返回日期的字符串,年月日 时:分
	 * 
	 * @param date
	 * @return yyyy-MM-dd HH:mm
	 */
	public static String getStrYMDHMByDate(Date date) {
		return getStrByDate(date, "yyyy-MM-dd HH:mm");
	}

	/**
	 * 对天数进行加减运算
	 * 
	 * @param date
	 *            原来的时间
	 * @param days
	 *            正数为加,负数为减
	 * @return 返回运算后的时间
	 */
	public static Date addDay(Date date, Integer days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, days);
		return calendar.getTime();
	}

	/**
	 * 对月数进行加减运算
	 * 
	 * @param date
	 *            原来的时间
	 * @param days
	 *            正数为加,负数为减
	 * @return 返回运算后的时间
	 */
	public static Date addMonth(Date date, Integer months) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, months);
		return calendar.getTime();
	}

	/**
	 * 返回中文时间格式
	 * 
	 * @param object
	 *            可以为Date对象或2007-06-12格式的字符串
	 * @return
	 */
	public static String toChinese(Object object) {
		String dateStr = null;
		if (object instanceof Date)
			dateStr = getStrYMDByDate((Date) object);
		else if (object instanceof String)
			dateStr = (String) object;
		else
			return dateStr;
		String[] cnArray = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
		String year = dateStr.split("-")[0];
		String month = dateStr.split("-")[1];
		String date = dateStr.split("-")[2];
		dateStr = "";
		for (int i = 0; i < year.length(); i++)
			dateStr += cnArray[Integer.valueOf(String.valueOf(year.charAt(i)))];
		dateStr += "年";
		if ("10".equals(month))
			dateStr += "十";
		else {
			int num = Integer.valueOf(String.valueOf(month.charAt(1)));
			if ("0".equals(String.valueOf(month.charAt(0))))
				dateStr += cnArray[num];
			else
				dateStr += "十" + cnArray[num];
		}
		dateStr += "月";
		if ("10".equals(date))
			dateStr += "十";
		else {
			String temp = String.valueOf(date.charAt(0));
			if ("1".equals(temp))
				dateStr += "十";
			else if ("2".equals(temp))
				dateStr += "二十";
			else if ("3".equals(temp))
				dateStr += "三十";
			if (!"0".equals(String.valueOf(date.charAt(1))))
				dateStr += cnArray[Integer.valueOf(String.valueOf(date.charAt(1)))];
		}
		dateStr += "日";
		return dateStr;
	}

	/**
	 * 返回星期几
	 * 
	 * @param object
	 *            Date对象或者字符串,yyyy-MM-dd
	 * @return 星期五
	 */
	public static String getWeek(Object object) {
		Calendar cal = Calendar.getInstance();
		Date date = null;
		if (object instanceof Date)
			date = (Date) object;
		else if (object instanceof String)
			date = getDateByStr((String) object);
		else
			return "";
		cal.setTime(date);
		String[] cnWeek = { "日", "一", "二", "三", "四", "五", "六" };
		return "星期" + cnWeek[cal.get(Calendar.DAY_OF_WEEK)];
	}

	public static Date get00_00_00Date(Date date) {
		return getDateByStr(getStrYMDByDate(date));
	}

	public static Date get23_59_59Date(Date date) {
		return getDateByStr(getStrYMDHMSByDate(date).substring(0, 10) + " 23:59:59");
	}

	public static Date getWeekStartDate_Sunday(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_WEEK, 1);
		return cal.getTime();
	}

	public static Date getWeekStartDate_Monday(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_WEEK, 2);
		return cal.getTime();
	}

	public static Date getWeekEndDate_Sunday(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if (1 == cal.get(Calendar.DAY_OF_WEEK))
			return date;
		cal.set(Calendar.DAY_OF_WEEK, 1);
		return DateUtil.addDay(cal.getTime(), 7);
	}

	public static Date getWeekEndDate_Saturday(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if (7 == cal.get(Calendar.DAY_OF_WEEK))
			return date;
		cal.set(Calendar.DAY_OF_WEEK, 7);
		return cal.getTime();
	}

	public static Date getDateByShortStr(String dateStr) {
		try {
			String[] dateStrArray = dateStr.split("-");
			String dateStrYear = "20" + dateStrArray[0];
			String dateStrMonth = dateStrArray[1];
			String dateStrDay = dateStrArray[2];
			if (1 == dateStrMonth.length())
				dateStrMonth = "0" + dateStrMonth;
			if (1 == dateStrDay.length())
				dateStrDay = "0" + dateStrDay;
			return getDateByStr(dateStrYear + "-" + dateStrMonth + "-" + dateStrDay);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String getMonthByShortEnglish(String string) {
		if (string.equals("Jan"))
			return "01";
		if (string.equals("Feb"))
			return "02";
		if (string.equals("Mar"))
			return "03";
		if (string.equals("Apr"))
			return "04";
		if (string.equals("May"))
			return "05";
		if (string.equals("Jun"))
			return "05";
		if (string.equals("Jul"))
			return "06";
		if (string.equals("Aug"))
			return "07";
		if (string.equals("Sep"))
			return "08";
		if (string.equals("Oct"))
			return "09";
		if (string.equals("Nov"))
			return "10";
		if (string.equals("Dec"))
			return "11";
		return "01";

	}

	/**
	 * 功能描述： 获得格式后的当前日期
	 * 
	 * @param date
	 *            Date 日期
	 * @return 返回当前日期
	 * @throws ParseException
	 */
	public static Date getNowDate(Date date) throws ParseException {
		SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
		return fm.parse(fm.format(date));
	}

	/**
	 * 功能描述： 获得当前日期的前一天
	 * 
	 * @param date
	 *            Date 日期
	 * @return 返回当前日期前一天
	 * @throws ParseException
	 */
	public static Date getUpDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		Date d = calendar.getTime();
		return getDate00_00_00(d);
	}

	/**
	 * 获取时间为00:00:00的日期
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date getDate00_00_00(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
		return getDateByStr(sdf.format(date));
	}

	/**
	 * 获取时间为00:00:00的日期
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date getDate00_00_00(String date) {
		Date d = getDateByStr(date);
		return getDate00_00_00(d);
	}

	/**
	 * 获取日期，格式：年月日
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date getDate(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return getDateByStr(sdf.format(date));
	}

	/**
	 * 获取时间为23:59:59的日期
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date getDate23_59_59(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
		return getDateByStr(sdf.format(date));
	}

	/**
	 * 获取时间为23:59:59的日期
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date getDate23_59_59(String date) {
		Date d = getDateByStr(date);
		return getDate23_59_59(d);
	}

	/**
	 * 获取月份起始日期
	 * 
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static String getMinMonthDate(String date) throws ParseException {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dateFormat.parse(date));
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取格式 2位年，2位日期，如1102表示为11年02月表示年月的整数值
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Integer getYearMonth(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyMM");
		return Integer.valueOf(sdf.format(date));
	}

	/**
	 * 获取格式 2位年，2位月，2位日期，如110228表示为11年02月28日表示年月的整数值
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static int getYearMonthDay(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
		return Integer.valueOf(sdf.format(date));
	}

	/**
	 * 2个日期直接相隔的天数
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 * @Author: seara
	 */
	public static int getDiffDay(Date startDate, Date endDate) {
		int day = 0;
		Date tem = DateUtil.getDate00_00_00(startDate);
		try {
			day = (int) ((endDate.getTime() - tem.getTime()) / (1000 * 24 * 3600));// 天数
		} catch (Exception e) {

		}
		return day;
	}

	/**
	 * 获取只有年月日的date格式的数据
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static Date getYMDDate(Date date) {
		return getDateByStr(getStrYMDByDate(date));
	}

	/**
	 * 获取当期时间的小时数
	 * 
	 * @return
	 * @Author: seara
	 */
	public static int getHour() {
		Calendar calendar = Calendar.getInstance();
		return calendar.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获得本周一的日期
	 * 
	 * @return
	 * @Author: 田振文
	 */
	public static String getMondayOFWeek() {
		int mondayPlus = getMondayPlus();
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.add(GregorianCalendar.DATE, mondayPlus);
		Date monday = currentDate.getTime();

		DateFormat df = DateFormat.getDateInstance();
		String preMonday = df.format(monday);
		return preMonday;
	}

	/**
	 * 获得当前日期与本周日相差的天数
	 * 
	 * @return
	 * @Author: 田振文
	 */
	private static int getMondayPlus() {
		Calendar cd = Calendar.getInstance();
		// 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
		int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
		if (dayOfWeek == 1) {
			return 0;
		} else {
			return 1 - dayOfWeek;
		}
	}

	/**
	 * 获得上月第一天
	 * 
	 * @return
	 * @Author: 田振文
	 */
	public static Date getPreviousMonthFirst() {
		Calendar lastDate = Calendar.getInstance();
		lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
		lastDate.add(Calendar.MONTH, -1);// 减一个月，变为下月的1号
		// lastDate.add(Calendar.DATE,-1);//减去一天，变为当月最后一天
		return lastDate.getTime();
	}

	/**
	 * 获得上月最后一天
	 * 
	 * @return
	 * @Author: 田振文
	 */
	public static Date getPreviousMonthLast() {
		Calendar lastDate = Calendar.getInstance();
		lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
		// lastDate.add(Calendar.MONTH,-1);//减一个月，变为下月的1号
		lastDate.add(Calendar.DATE, -1);// 减去一天，变为当月最后一天
		return lastDate.getTime();
	}

	/**
	 * 获取当月第一天
	 * 
	 * @return
	 * @Author: 田振文
	 */
	public static Date getFirstDayOfMonth() {
		Calendar lastDate = Calendar.getInstance();
		lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
		return lastDate.getTime();
	}

	/**
	 * 获得本季度的第一天
	 * 
	 * @param month
	 * @return
	 * @Author: 田振文
	 */
	public static String getThisSeasonTime(int month) {
		int array[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };
		int season = 1;
		if (month >= 1 && month <= 3) {
			season = 1;
		}
		if (month >= 4 && month <= 6) {
			season = 2;
		}
		if (month >= 7 && month <= 9) {
			season = 3;
		}
		if (month >= 10 && month <= 12) {
			season = 4;
		}
		int start_month = array[season - 1][0];
		// int end_month = array[season-1][2];
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");// 可以方便地修改日期格式
		String years = dateFormat.format(date);
		int years_value = Integer.parseInt(years);

		int start_days = 1;// years+"-"+String.valueOf(start_month)+"-1";//getLastDayOfMonth(years_value,start_month);
		// int end_days = getLastDayOfMonth(years_value,end_month);
		String seasonDate = years_value + "-" + start_month + "-" + start_days;
		// +";"+years_value+"-"+end_month+"-"+end_days
		return seasonDate;

	}

	/**
	 * 是否闰年
	 * 
	 * @param year
	 *            年
	 * @return
	 */
	public static boolean isLeapYear(int year) {
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}

	/**
	 * 得到几天前的时间
	 * 
	 * @param d
	 * @param day
	 * @return
	 */
	public static Date getDateBefore(Date d, int day) {
		Calendar now = Calendar.getInstance();
		now.setTime(d);
		now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
		return now.getTime();
	}

	/**
	 * 得到二个日期间的间隔天数
	 * 
	 * @param da1
	 *            距离现在较近的日期
	 * 
	 * @param da2
	 *            距离现在较远的日期
	 * 
	 * @return 相隔的天数(String)
	 * 
	 * @Author: 田振文
	 */
	public static String getTwoDay(Date da1, Date da2) {
		long day = 0;
		try {
			day = (da1.getTime() - da2.getTime()) / (24 * 60 * 60 * 1000);
		} catch (Exception e) {
			return "";
		}
		return String.valueOf(day);
	}

	/**
	 * 得到指定日期的月初 格式为：xxxx-yy-zz (eg: 2007-12-01)
	 * 
	 * @param date
	 * @return
	 * @Author: seara
	 */
	public static String getMonthStart(Date date) {
		String month = null;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int x = c.get(Calendar.YEAR);
		int y = c.get(Calendar.MONTH) + 1;
		month = (y >= 10 ? String.valueOf(y) : ("0" + y));
		return x + "-" + month + "-01";
	}

	/**
	 * 得到指定日期的月底 格式为：xxxx-yy-zz (eg: 2007-12-31)
	 * 
	 * @return String
	 * @author seara
	 */
	public static String getMonthEnd(Date date) {
		String day = null;
		boolean leap = false;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int x = c.get(Calendar.YEAR);
		int y = c.get(Calendar.MONTH) + 1;
		if (y == 1 || y == 3 || y == 5 || y == 7 || y == 8 || y == 10 || y == 12) {
			day = "31";
		}
		if (y == 4 || y == 6 || y == 9 || y == 11) {
			day = "30";
		}
		if (y == 2) {
			leap = leapYear(x);
			if (leap) {
				day = "29";
			} else {
				day = "28";
			}
		}
		String month = (y >= 10 ? String.valueOf(y) : ("0" + y));
		return x + "-" + month + "-" + day;
	}

	/**
	 * 功能：判断输入年份是否为闰年
	 * 
	 * @param year
	 * @return 是：true 否：false
	 * @author seara
	 */
	private static boolean leapYear(int year) {
		boolean leap;
		if (year % 4 == 0) {
			if (year % 100 == 0) {
				if (year % 400 == 0)
					leap = true;
				else
					leap = false;
			} else
				leap = true;
		} else
			leap = false;
		return leap;
	}
}